package com.luhuiguo.cms.server.webdav;

import java.io.IOException;
import java.util.Date;

import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bradmcevoy.http.Auth;
import com.bradmcevoy.http.DeletableResource;
import com.bradmcevoy.http.DigestResource;
import com.bradmcevoy.http.LockInfo;
import com.bradmcevoy.http.LockResult;
import com.bradmcevoy.http.LockTimeout;
import com.bradmcevoy.http.LockToken;
import com.bradmcevoy.http.LockableResource;
import com.bradmcevoy.http.PropFindableResource;
import com.bradmcevoy.http.Request;
import com.bradmcevoy.http.Resource;
import com.bradmcevoy.http.Request.Method;
import com.bradmcevoy.http.exceptions.NotAuthorizedException;
import com.bradmcevoy.http.http11.auth.DigestResponse;

public class GaeResource implements Resource, DeletableResource, PropFindableResource, LockableResource, DigestResource {

    private static final Logger logger = LoggerFactory.getLogger(GaeResource.class);

    FileObject fileObject;

    final GaeResourceFactory factory;

    final String host;

    public GaeResource(String host, GaeResourceFactory factory, FileObject fileObject) {
        this.host = host;
        this.fileObject = fileObject;
        this.factory = factory;
    }

    public FileObject getFileObject() {
        return fileObject;
    }

    @Override
    public String getUniqueId() {
        return fileObject.hashCode() + "";
    }

    @Override
    public String getName() {
        try {
            if (fileObject.getParent() == null) {
                return "/";
            }
        } catch (FileSystemException e) {
            e.printStackTrace();
            return "";
        }
        return fileObject.getName().getBaseName();
    }

    @Override
    public Object authenticate(String user, String password) {
        return factory.getSecurityManager().authenticate(user, password);
    }

    @Override
    public Object authenticate(DigestResponse digestRequest) {
        return factory.getSecurityManager().authenticate(digestRequest);
    }

    @Override
    public boolean authorise(Request request, Method method, Auth auth) {
        return factory.getSecurityManager().authorise(request, method, auth, this);
    }

    @Override
    public String getRealm() {
        return factory.getRealm(host);
    }

    @Override
    public Date getModifiedDate() {
        try {
            if (!fileObject.exists()) {
                return null;
            }
            return new Date(fileObject.getContent().getLastModifiedTime());
        } catch (FileSystemException e) {
            return null;
        }
    }

    @Override
    public Date getCreateDate() {
        return null;
    }

    @Override
    public String checkRedirect(Request request) {
        return null;
    }

    @Override
    public void delete() {
        try {
            final boolean deleted = fileObject.delete();
            if (!deleted)
                throw new IOException("File " + getName() + " not deleted");
        } catch (IOException e) {
            logger.warn(e.getMessage(), e);
            // e.printStackTrace();
        }
    }

    @Override
    public LockToken getCurrentLock() {
        if (factory.getLockManager() != null) {
            return factory.getLockManager().getCurrentToken(this);
        } else {
            logger.warn("getCurrentLock called, but no lock manager: file: {}" + fileObject.getName());
            return null;
        }
    }

    @Override
    public LockResult lock(LockTimeout timeout, LockInfo lockInfo) throws NotAuthorizedException {
        return factory.getLockManager().lock(timeout, lockInfo, this);
    }

    @Override
    public LockResult refreshLock(String token) throws NotAuthorizedException {
        return factory.getLockManager().refresh(token, this);
    }

    @Override
    public void unlock(String tokenId) throws NotAuthorizedException {
        factory.getLockManager().unlock(tokenId, this);
    }

}
